home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UFloatWindow.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  25.9 KB  |  943 lines  |  [TEXT/MPS ]

  1. //$P
  2. //[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]
  3. // UFloatWindow.cp 
  4. // Copyright © 1987-1991 by Apple Computer Inc.    All rights reserved.
  5.  
  6. #ifndef __UFLOATWINDOW__
  7. #include "UFloatWindow.h"
  8. #endif
  9.  
  10. #ifndef __GEOMETRY__
  11. #include <Geometry.h>
  12. #endif
  13.  
  14. #ifndef __TOOLUTILS__
  15. #include <ToolUtils.h>
  16. #endif
  17.  
  18. #ifndef __DESK__
  19. #include <Desk.h>
  20. #endif
  21.  
  22. #ifndef __PALETTES__
  23. #include <Palettes.h>
  24. #endif
  25.  
  26. #ifndef __UAPPLICATION__
  27. #include <UApplication.h>
  28. #endif
  29.  
  30. #ifndef __UMACAPPUTILITIES__
  31. #include <UMacAppUtilities.h>
  32. #endif
  33.  
  34. #ifndef __UMACAPPGLOBALS__
  35. #include <UMacAppGlobals.h>
  36. #endif
  37.  
  38. #ifndef __SYSEQU__
  39. #include <SysEqu.h>
  40. #endif
  41.  
  42.  
  43. //--------------------------------------------------------------------------------------------------
  44. typedef WindowPtr* WindowPtrPtr;                // used to access low memory globals 
  45.  
  46. //--------------------------------------------------------------------------------------------------
  47. const short kTHINKWindowKind = 32700;
  48. const short kWindoidWDEF = 48;                    //(16 * 3);                        // !!! our default windoid WDEF 
  49.  
  50. //--------------------------------------------------------------------------------------------------
  51. /* The Layer Mgr included as of System 7.0 and AUX 2.0 presents problems with the Window Mgr patches
  52.   we've installed. Specifically, the problems are that when switching in an application that has
  53.   been switched out under MultiFinder, the application's patches are re-installed prior to the
  54.   application's layer being pulled to front. So, the patches are re-installed and then MF calls
  55.   SelectWindow on the application's layer. However, our patches get control and they need to know
  56.   if the windowPtr that SelectWindow has been handed is a real window or a layer. The only way to
  57.   know is to make a call to the Layer Mgr. However, the Layer Mgr interfaces aren't public, so we
  58.   have to make our own interface to the one Layer Mgr call that we need: IsLayer. This problem _may_
  59.   be fixed if MultiFinder is modified so that it pulls the application's layer to the front
  60.  *before* re-installing the application's patches. */
  61.  
  62. #ifdef __cplusplus
  63. extern "C"
  64. {
  65. #endif
  66.  
  67.     pascal Boolean MAIsLayer(WindowPtr window) = {
  68.                                                   0x7002, 0xA829};
  69. #ifdef __cplusplus
  70. }
  71. #endif
  72.  
  73. //--------------------------------------------------------------------------------------------------
  74. Boolean gUFloatWindowInitialized = FALSE;        // declared in header
  75.  
  76. //--------------------------------------------------------------------------------------------------
  77. TrapPatch pBringToFrontPatch;
  78. TrapPatch pDragWindowPatch;
  79. TrapPatch pSelectWindowPatch;
  80. TrapPatch pMoveWindowPatch;
  81. TrapPatch pZoomWindowPatch;
  82. TrapPatch pShowWindowPatch;
  83. TrapPatch pShowHidePatch;
  84. TrapPatch pHiliteWindowPatch;
  85. TrapPatch pNewDialogPatch;
  86.  
  87. // GNE patch record to manage window mgr low memory globals 
  88. TrapPatch pGetNextEventPatch;
  89.  
  90. // private globals needed by window mgr patches 
  91. Boolean pHasLayerMgr;                            // flag tells us if the Layer Mgr is in 
  92. Boolean pDuringSelectWindow;                    /* flag to correctly handle re-entrancy
  93.                                                   problems in SelectWindow */
  94.  
  95. //--------------------------------------------------------------------------------------------------
  96. #pragma $Push
  97. #if qTrace
  98. #pragma $D+
  99. #endif
  100.  
  101. #pragma $R-
  102. #pragma $V-
  103. #pragma segment MAWindowRes
  104.  
  105. pascal void FixedSendBehind(WindowPtr window,
  106.                             WindowPtr behind,
  107.                             Boolean doActivatePalette)
  108.  
  109. {
  110.     WindowPeek windPeek;
  111.     GrafPtr savePort;
  112.     RgnHandle clobbered;
  113.     Point rgnTopLeft;
  114.  
  115.     // set up 
  116.     windPeek = (WindowPeek)window;
  117.     GetPort(savePort);
  118.     SetPort(window);
  119.  
  120.     // create a rgn so that we can figure out what rgn needs to be recalculated 
  121.     clobbered = NewRgn();                        // …don't call MakeNewRgn from patch 
  122.     CopyRgn(window->visRgn, clobbered);
  123.  
  124.     // convert the rgn into globals 
  125.     rgnTopLeft = (*clobbered)->rgnBBox[topLeft];
  126.     LocalToGlobal(rgnTopLeft);
  127.     OffsetRgn(clobbered, rgnTopLeft.h - (*clobbered)->rgnBBox.left, rgnTopLeft.v - (*clobbered)->rgnBBox.top);
  128.  
  129.     // put that window where it belongs and activate its palette if requested 
  130.     SendBehind(window, behind);
  131.     if ((qNeedsColorQD || gConfiguration.hasColorQD) && doActivatePalette)
  132.         ActivatePalette(window);
  133.  
  134.     // figure out what needs to be painted, paint it, and recalculate vis rgns 
  135.     DiffRgn(windPeek->strucRgn, clobbered, clobbered);
  136.     PaintOne(windPeek, clobbered);
  137.     CalcVisBehind(windPeek, clobbered);            //windPeek->strucRgn
  138.  
  139.     // clean up 
  140.     DisposeRgn(clobbered);
  141.     SetPort(savePort);
  142. }
  143. #pragma $Pop
  144.  
  145. //--------------------------------------------------------------------------------------------------
  146. #pragma $Push
  147. #if qTrace
  148. #pragma $D+
  149. #endif
  150.  
  151. #pragma $R-
  152. #pragma $V-
  153. #pragma segment MAWindowRes
  154.  
  155. pascal void CallBringToFront(WindowPtr window,
  156.                              long oldTrap) = {
  157.                                               0x205F, 0x4E90};
  158.  
  159. pascal void MABringToFront(WindowPtr window)
  160.  
  161. // Patch for BringToFront that preserves window layering:
  162. //    • for floaters, leave the routine && call the real BringToFront;
  163. //    • for dialogs, leave the routine && call the real BringToFront;
  164. //    • if no floaters, leave the routine && call the real BringToFront;
  165. //    • otherwise, call SendBehind
  166.  
  167. {
  168.     long oldA5 = SetCurrentA5();
  169.     WindowPtr lastFloatingWindowPtr;
  170.     WindowPeek windPeek;
  171.     WindowPtr activeWindow;
  172.  
  173.     windPeek = ((WindowPeek)window);
  174.  
  175.     if (IsFloatWindow(window))
  176.     {
  177.         /* • Floaters: call the real BringToFront;*/
  178.         if (gApplication->IsFrontProcess() && (window != FrontWindow()))
  179.             CallBringToFront(window, pBringToFrontPatch.oldTrapAddr);
  180.     }
  181.     else
  182.     {
  183.         if ((pHasLayerMgr && MAIsLayer(window)) || (windPeek->windowKind < 0))
  184.             CallBringToFront(window, pBringToFrontPatch.oldTrapAddr);/* • Layers or System Windows: call
  185.                                                   the real BringToFront;*/
  186.  
  187.         else
  188.         {
  189.             if (IsDialog(window))
  190.             {
  191.                 /* • Dialogs: call the real BringToFront and
  192.                   then de-hilite and deactivate the active
  193.                   window*/
  194.                 // bring the dialog to the front 
  195.                 CallBringToFront(window, pBringToFrontPatch.oldTrapAddr);
  196.  
  197.                 // de-hilite the active window and deactivate it 
  198.                 activeWindow = MAGetActiveWindow();
  199.                 if ((activeWindow) && (activeWindow != window))
  200.                 {
  201.                     HiliteWindow(activeWindow, FALSE);
  202.                     *((WindowPtrPtr)CurDeactive) = activeWindow;// set curDeactive 
  203.                     if (activeWindow)
  204.                         *((IntegerPtr)CurDeKind) = ((WindowPeek)activeWindow)->windowKind;
  205.                 }
  206.             }
  207.             else
  208.             {                                    /* • Document windows */
  209.                 lastFloatingWindowPtr = GetLastFloatingWindowPtr();
  210.                 if (!lastFloatingWindowPtr)        /* • if no floaters, call the real
  211.                                                   BringToFront*/
  212.                     CallBringToFront(window, pBringToFrontPatch.oldTrapAddr);
  213.                 else                            /* • if there are floaters, call SendBehind*/
  214.                     {
  215.                         SendSystemWindowsToBack();// send system windows to back 
  216.                         FixedSendBehind(window, lastFloatingWindowPtr, TRUE);
  217.                     }
  218.             }
  219.         }
  220.     }
  221.     SetA5(oldA5);
  222. }
  223. #pragma $Pop
  224.  
  225. //--------------------------------------------------------------------------------------------------
  226. #pragma $Push
  227. #if qTrace
  228. #pragma $D+
  229. #endif
  230.  
  231. #pragma $R-
  232. #pragma $V-
  233. #pragma segment MAWindowRes
  234.  
  235. pascal void MADragWindow(WindowPtr window,
  236.                          Point startPt,
  237.                          Rect bounds)
  238.  
  239. // Complete replacement of DragWindow that preserves window layering. 
  240.  
  241. {
  242.     const short kCommandKey = 55;
  243.  
  244.     long oldA5 = SetCurrentA5();
  245.     GrafPtr wMgrPort;
  246.     GrafPtr savePort;
  247.     RgnHandle dragRgn;
  248.     long result;
  249.     Point newLoc;
  250.     Rect portBounds;
  251.     RgnHandle tempRgn;
  252.     WindowPtr clipWindow;
  253.     Boolean commandFlag;
  254.     KeyMap theKeys;
  255.  
  256.     // set up some parameters 
  257.     GetKeys(theKeys);
  258.     commandFlag = BitTst((Ptr)theKeys, kCommandKey);
  259.     if (StillDown())
  260.     {
  261.         GetPort(savePort);
  262.         GetWMgrPort(wMgrPort);
  263.         SetPort(wMgrPort);
  264.  
  265.         tempRgn = NewRgn();                        // what if NewRgn returns NULL??? 
  266.         GetClip(tempRgn);
  267.  
  268.         // drag the gray outline 
  269.         if (commandFlag)
  270.             clipWindow = window;                // we won't be activating this window 
  271.         else if (IsFloatWindow(window) || (((WindowPeek)window)->windowKind < 0))
  272.             clipWindow = FrontWindow();            // floaters && DAs get dragged at front 
  273.         else
  274.         {
  275.             SendSystemWindowsToBack();            // send system windows to back 
  276.             clipWindow = MAFrontWindow();
  277.         }
  278.         MAClipAbove(clipWindow);
  279.         dragRgn = NewRgn();                        // what if NewRgn returns NULL??? 
  280.         CopyRgn(((WindowPeek)window)->strucRgn, dragRgn);
  281.         result = DragGrayRgn(dragRgn, startPt, bounds, bounds, noConstraint, NULL);
  282.  
  283.         SetClip(tempRgn);
  284.         DisposeRgn(tempRgn);
  285.         DisposeRgn(dragRgn);
  286.  
  287.         // determine what to do with the window 
  288.         newLoc.v = HiWord(result);
  289.         newLoc.h = LoWord(result);
  290.         if (newLoc.v == 0x8000)
  291.         {
  292.             // in certain situations, we sent the system windows to back.
  293.             //Since we sent the system windows to back, we need to activate the front
  294.             //window if it is now the front document window. 
  295.             if ((!commandFlag) && (!IsFloatWindow(window)) && (((WindowPeek)window)->windowKind >= 0) && (((WindowPeek)window)->windowKind < kTHINKWindowKind))
  296.                 SelectWindow(window);
  297.         }
  298.         else
  299.         {
  300.             if ((((CGrafPtr)window)->portVersion & 0xC000) != 0)
  301.                 portBounds = (*((CGrafPtr)window)->portPixMap)->bounds;
  302.             else
  303.                 portBounds = window->portBits.bounds;
  304.  
  305.             newLoc += window->portRect[topLeft] - portBounds[topLeft];
  306.             MoveWindow(window, newLoc.h, newLoc.v, FALSE);
  307.             if (!commandFlag)
  308.                 SelectWindow(window);
  309.         }
  310.  
  311.         // restore various values 
  312.         SetPort(savePort);
  313.     }
  314.  
  315.     SetA5(oldA5);
  316. }
  317. #pragma $Pop
  318.  
  319. //--------------------------------------------------------------------------------------------------
  320. #pragma $Push
  321. #if qTrace
  322. #pragma $D+
  323. #endif
  324.  
  325. #pragma $R-
  326. #pragma $V-
  327. #pragma segment MAWindowRes
  328.  
  329. WindowPtr pFrontWindow;                            /* stores the reference to the window that
  330.                                                   the MAFrontWindow patch should return */
  331. TrapPatch pFrontWindowPatch;
  332.  
  333. pascal WindowPtr FrontWindowPatch(void)            /* patch to FrontWindow that is active while
  334.                                                   calling ActivatePalette */
  335.  
  336. {
  337.     return pFrontWindow;
  338. }
  339.  
  340.  
  341. pascal void MAActivatePalette(WindowPtr window)
  342. // ensures that the call to ActivatePalette on "window" actually takes effect 
  343.  
  344. {
  345.     Boolean needsFrontWindowPatch;
  346.  
  347.     pFrontWindow = window;
  348.     needsFrontWindowPatch = FrontWindow() != window;
  349.     if (needsFrontWindowPatch)                    /* patch FrontWindow so that it returns the
  350.                                                   "window" */
  351.         FailOSErr(PatchTrap(pFrontWindowPatch, _FrontWindow, (Ptr) & FrontWindowPatch));
  352.     ActivatePalette(window);
  353.     if (needsFrontWindowPatch)
  354.         UnpatchTrap(pFrontWindowPatch);
  355. }
  356.  
  357. #pragma $Pop
  358.  
  359. //--------------------------------------------------------------------------------------------------
  360. #pragma $Push
  361. #if qTrace
  362. #pragma $D+
  363. #endif
  364.  
  365. #pragma $R-
  366. #pragma $V-
  367. #pragma segment MAWindowRes
  368.  
  369. pascal void CallSelectWindow(WindowPtr window,
  370.                              long oldTrap) = {
  371.                                               0x205F, 0x4E90};
  372.  
  373. pascal void MASelectWindow(WindowPtr window)
  374. // Patch for SelectWindow that preserves window layering. 
  375.  
  376. {
  377.     long oldA5 = SetCurrentA5();
  378.     GrafPtr savePort;
  379.     WindowPtr activeWindow;
  380.  
  381.     if (!pDuringSelectWindow)
  382.     {
  383.         if (pHasLayerMgr && MAIsLayer(window))
  384.             CallSelectWindow(window, pSelectWindowPatch.oldTrapAddr);
  385.         else
  386.         {
  387.             GetPort(savePort);
  388.  
  389.             if (IsFloatWindow(window))
  390.             {
  391.                 BringToFront(window);
  392.  
  393.                 /* for color environments, set the floater's palette to be the active
  394.                   palette iff the active window has no palette */
  395.                 if (qNeedsColorQD || gConfiguration.hasColorQD)
  396.                 {
  397.                     activeWindow = MAGetActiveWindow();
  398.                     if (!GetPalette(activeWindow))
  399.                         ActivatePalette(window);
  400.                 }
  401.             }
  402.             else
  403.             {
  404.                 // unhilite and deactivate the active document window 
  405.                 activeWindow = MAGetActiveWindow();
  406.                 if ((activeWindow) && (activeWindow != window))
  407.                 {
  408.                     HiliteWindow(activeWindow, FALSE);
  409.                     *((WindowPtrPtr)CurDeactive) = activeWindow;// set curDeactive 
  410.                     if (activeWindow)
  411.                         *((IntegerPtr)CurDeKind) = ((WindowPeek)activeWindow)->windowKind;
  412.                 }
  413.  
  414.                 // move the window to the correct position, hilite, and activate it 
  415.                 pDuringSelectWindow = TRUE;
  416.                 BringToFront(window);
  417.                 pDuringSelectWindow = FALSE;
  418.                 HiliteWindow(window, TRUE);
  419.                 if (((WindowPeek)window)->visible)
  420.                     *((WindowPtrPtr)CurActivate) = window;// set curActivate 
  421.  
  422.                 if (qNeedsColorQD || gConfiguration.hasColorQD)
  423.                     MAActivatePalette(window);
  424.             }
  425.             SetPort(savePort);
  426.         }
  427.     }
  428.     SetA5(oldA5);
  429. }
  430. #pragma $Pop
  431.  
  432. //--------------------------------------------------------------------------------------------------
  433. #pragma $Push
  434. #if qTrace
  435. #pragma $D+
  436. #endif
  437.  
  438. #pragma $R-
  439. #pragma $V-
  440. #pragma segment MAWindowRes
  441.  
  442. pascal void CallMoveWindow(WindowPtr theWindow,
  443.                            short hGlobal,
  444.                            short vGlobal,
  445.                            Boolean front,
  446.                            long oldTrap) = {
  447.                                             0x205F, 0x4E90};
  448.  
  449. pascal void MAMoveWindow(WindowPtr theWindow,
  450.                          short hGlobal,
  451.                          short vGlobal,
  452.                          Boolean front)
  453. // Tail Patch for MoveWindow that preserves window layering.
  454. //    We do this b/c MoveWindow doesn't call SelectWindow trap, instead jumps directly there
  455.  
  456. {
  457.     long oldA5 = SetCurrentA5();
  458.  
  459.     // force FALSE for "front" parameter 
  460.     CallMoveWindow(theWindow, hGlobal, vGlobal, FALSE, pMoveWindowPatch.oldTrapAddr);
  461.  
  462.     if (front)
  463.         SelectWindow(theWindow);
  464.     SetA5(oldA5);
  465. }
  466. #pragma $Pop
  467.  
  468. //--------------------------------------------------------------------------------------------------
  469. #pragma $Push
  470. #if qTrace
  471. #pragma $D+
  472. #endif
  473.  
  474. #pragma $R-
  475. #pragma $V-
  476. #pragma segment MAWindowRes
  477.  
  478. pascal void CallZoomWindow(WindowPtr theWindow,
  479.                            short partCode,
  480.                            Boolean front,
  481.                            long oldTrap) = {
  482.                                             0x205F, 0x4E90};
  483.  
  484. pascal void MAZoomWindow(WindowPtr theWindow,
  485.                          short partCode,
  486.                          Boolean front)
  487.  
  488. {
  489.     long oldA5 = SetCurrentA5();
  490.  
  491.     // force FALSE for "front" parameter 
  492.     CallZoomWindow(theWindow, partCode, FALSE, pZoomWindowPatch.oldTrapAddr);
  493.  
  494.     if (front)
  495.         SelectWindow(theWindow);
  496.     SetA5(oldA5);
  497. }
  498. #pragma $Pop
  499.  
  500. //--------------------------------------------------------------------------------------------------
  501. #pragma $Push
  502. #if qTrace
  503. #pragma $N+
  504. #endif
  505.  
  506. #pragma $D-
  507. #pragma $R-
  508. #pragma $V-
  509. #pragma segment MAWindowRes
  510.  
  511. pascal void CallHiliteWindow(WindowPtr theWindow,
  512.                              Boolean fHilite,
  513.                              long oldTrap) = {
  514.                                               0x205F, 0x4E90};
  515.  
  516. pascal void MAHiliteWindow(WindowPtr theWindow,
  517.                            Boolean fHilite)
  518.  
  519. // Patch to HiliteWindow which ensures that the correct window gets hilited/dehilited 
  520. // during call to NewDialog.
  521.  
  522. {
  523.     long oldA5 = SetCurrentA5();
  524.     WindowPtr toHilite;
  525.  
  526.     if (((WindowPeek)theWindow)->visible)
  527.     {
  528.         if (!IsFloatWindow(theWindow))
  529.             CallHiliteWindow(theWindow, fHilite, pHiliteWindowPatch.oldTrapAddr);
  530.         else
  531.         {
  532.             if (fHilite)
  533.             {
  534.                 toHilite = MAFrontWindow();
  535.                 *((WindowPtrPtr)CurActivate) = toHilite;// set curActivate 
  536.             }
  537.             else
  538.             {
  539.                 toHilite = MAGetActiveWindow();
  540.                 *((WindowPtrPtr)CurDeactive) = toHilite;// set CurDeactive 
  541.                 if (toHilite)
  542.                     *((IntegerPtr)CurDeKind) = WindowPeek(toHilite)->windowKind;
  543.             }
  544.             if (toHilite)
  545.                 CallHiliteWindow(toHilite, fHilite, pHiliteWindowPatch.oldTrapAddr);
  546.         }
  547.     }
  548.  
  549.     SetA5(oldA5);
  550. }
  551. #pragma $Pop
  552.  
  553. //--------------------------------------------------------------------------------------------------
  554. #pragma $Push
  555. #if qTrace
  556. #pragma $N+
  557. #endif
  558.  
  559. #pragma $D-
  560. #pragma $R-
  561. #pragma $V-
  562. #pragma segment MAWindowRes
  563.  
  564. pascal DialogPtr CallNewDialog(void *wStorage,const Rect& boundsRect,ConstStr255Param title,
  565.     Boolean visible,short procID,WindowPtr behind,Boolean goAwayFlag,long refCon,
  566.     Handle itmLstHndl, long oldTrap) = {0x205F, 0x4E90};
  567.  
  568. pascal DialogPtr MANewDialog(void *wStorage,const Rect& boundsRect,ConstStr255Param title,
  569.     Boolean visible,short procID,WindowPtr behind,Boolean goAwayFlag,long refCon,
  570.     Handle itmLstHndl)
  571. {
  572.     long oldA5 = SetCurrentA5();
  573.     Boolean needsHiliteWindowPatch = IsFloatWindow(FrontWindow());
  574.     if (needsHiliteWindowPatch)
  575.         FailOSErr(PatchTrap(pHiliteWindowPatch, _HiliteWindow, (Ptr) & MAHiliteWindow));
  576.     DialogPtr aDialogPtr = CallNewDialog(wStorage, boundsRect, title, visible, procID, behind,
  577.                             goAwayFlag, refCon, itmLstHndl, pNewDialogPatch.oldTrapAddr);
  578.     if (needsHiliteWindowPatch)
  579.         UnpatchTrap(pHiliteWindowPatch);
  580.     SetA5(oldA5);
  581.     return aDialogPtr;
  582. }
  583.  
  584. #pragma $Pop
  585.  
  586. //--------------------------------------------------------------------------------------------------
  587. #pragma $Push
  588. #if qTrace
  589. #pragma $D+
  590. #endif
  591.  
  592. #pragma $R-
  593. #pragma $V-
  594. #pragma segment MAWindowRes
  595.  
  596. pascal void CallShowWindow(WindowPtr theWindow,
  597.                            long oldTrap) = {
  598.                                             0x205F, 0x4E90};
  599.  
  600. pascal void MAShowWindow(WindowPtr theWindow)
  601. // tail patch to ShowWindow which ensures that SelectWindow gets called for a shown window 
  602.  
  603. {
  604.     long oldA5 = SetCurrentA5();
  605.     if (!WindowPeek(theWindow)->visible)
  606.     {
  607.         CallShowWindow(theWindow, pShowWindowPatch.oldTrapAddr);
  608.         if (MAFrontWindow() == theWindow)
  609.             SelectWindow(theWindow);
  610.     }
  611.     SetA5(oldA5);
  612. }
  613. #pragma $Pop
  614.  
  615. //--------------------------------------------------------------------------------------------------
  616. #pragma $Push
  617. #if qTrace
  618. #pragma $D+
  619. #endif
  620.  
  621. #pragma $R-
  622. #pragma $V-
  623. #pragma segment MAWindowRes
  624.  
  625. pascal void CallShowHide(WindowPtr theWindow,
  626.                          Boolean showFlag,
  627.                          long oldTrap) = {
  628.                                           0x205F, 0x4E90};
  629.  
  630. pascal void MAShowHide(WindowPtr theWindow,
  631.                        Boolean showFlag)
  632.  
  633. // This patch manages the global pActiveWindow, and activates the next document window in the case
  634. //where we're hiding the currently active document window and there are floaters present.
  635. //
  636. //  Note that this patch to ShowHide actually gets called from 5 other traps, since:
  637. //
  638. //        HideWindow calls ShowHide
  639. //        CloseWindow calls ShowHide
  640. //        DisposWindow calls CloseWindow
  641. //        CloseDialog calls CloseWindow
  642. //        DisposDialog calls CloseDialog
  643. //
  644. //  So, ShowHide is the routine through which all other Window Mgr routines eventually bottleneck to
  645. //actually hide the window.
  646.  
  647. {
  648.     long oldA5 = SetCurrentA5();
  649.     Boolean needActivate;
  650.     WindowPtr toActivate;
  651.  
  652.     // if we're hiding a front document window that's not the actual front window (i.e. it's in back
  653.     //    of a floater) then we need to select the next document window
  654.     needActivate = (!showFlag) && (theWindow == MAFrontWindow()) && (FrontWindow() != theWindow);
  655.  
  656.     CallShowHide(theWindow, showFlag, pShowHidePatch.oldTrapAddr);
  657.  
  658.     // activate the next window if necessary 
  659.     if (needActivate)
  660.     {
  661.         toActivate = MAFrontWindow();
  662.         if (toActivate)
  663.         {
  664.             // instead, call SelectWindow ??? 
  665.             *((WindowPtrPtr)CurActivate) = toActivate;// set curActivate 
  666.             HiliteWindow(toActivate, TRUE);
  667.         }
  668.     }
  669.  
  670.     SetA5(oldA5);
  671. }
  672. #pragma $Pop
  673.  
  674. //--------------------------------------------------------------------------------------------------
  675. #pragma $Push
  676. #if qTrace
  677. #pragma $N+
  678. #endif
  679.  
  680. #pragma $D-
  681. #pragma $R-
  682. #pragma $V-
  683. #pragma segment MAWindowRes
  684.  
  685. pascal Boolean CallGetNextEvent(short eventMask,
  686.                                 EventRecord& theEvent,
  687.                                 long oldTrap) = {
  688.                                                  0x205F, 0x4E90};
  689.  
  690. pascal Boolean MAGetNextEvent(short eventMask,
  691.                               EventRecord& theEvent)
  692.  
  693. // tail patch to GetNextEvent that:
  694. //    • redirects activate events from floating windows to front doc window
  695. //    • redirects deactivate events from floating windows to front doc window
  696.  
  697. {
  698.     long oldA5 = SetCurrentA5();
  699.     WindowPtr myToActivate;
  700.     Boolean result;
  701.  
  702.     result = CallGetNextEvent(eventMask, theEvent, pGetNextEventPatch.oldTrapAddr);
  703.  
  704.     switch (theEvent.what)
  705.     {
  706.         case activateEvt:
  707.             if ((theEvent.modifiers & 1) == 1)    // • activate event 
  708.             {
  709.                 // redirect all activate calls from float windows to the front, non-floater window 
  710.                 if (IsFloatWindow((WindowPtr)theEvent.message))
  711.                 {
  712.                     myToActivate = MAFrontWindow();// the front, non-floater window 
  713.                     if (!myToActivate)
  714.                         theEvent.what = nullEvent;// …then zap the activate event! 
  715.                     else
  716.                     {
  717.                         HiliteWindow(myToActivate, TRUE);// restore hiliting 
  718.                         theEvent.message = (long)myToActivate;// redirect activate event 
  719.                     }
  720.                 }
  721.             }
  722.             else                                // • deactivate event 
  723.                 // redirect all deactivate calls from float windows to the active window 
  724.                 if (IsFloatWindow((WindowPtr)theEvent.message))// if deactivate evt is for floater 
  725.                     theEvent.what = nullEvent;    // …then zap the deactivate event! 
  726.             break;
  727.         case osEvt:
  728.             if (((theEvent.message & osEvtMessageMask) >> 24) == suspendResumeMessage)
  729.             {
  730.                 myToActivate = MAFrontWindow();    // the front, non-floater window 
  731.                 if (myToActivate)
  732.                     HiliteWindow(myToActivate, (theEvent.message & 1) == 1);// switching in/out 
  733.             }
  734.             break;
  735.     }                                            // switch what  
  736.  
  737.     SetA5(oldA5);
  738.     return result;
  739. }
  740. #pragma $Pop
  741. //--------------------------------------------------------------------------------------------------
  742. #pragma segment MAOpen
  743.  
  744. pascal void TFloatWindow::IFloatWindow(TDocument* itsDocument,
  745.                                        WindowPtr itsWMgrWindow,
  746.                                        Boolean canResize,
  747.                                        Boolean canClose,
  748.                                        Boolean disposeOnFree)
  749.  
  750. {
  751.     Point saveStdWTopleft;
  752.  
  753.     saveStdWTopleft = gStdWSizeRect[topLeft];
  754.     gStdWSizeRect[topLeft] = gZeroPt;
  755.     this->IWindow(itsDocument, itsWMgrWindow, canResize, canClose, disposeOnFree);
  756.     gStdWSizeRect[topLeft] = saveStdWTopleft;
  757.  
  758.     fHideOnSuspend = TRUE;
  759.     fDoFirstClick = TRUE;
  760.     fFloats = TRUE;
  761.     ((WindowPeek)itsWMgrWindow)->windowKind = kFloatWindowKind;// mark it as a floating window 
  762.     fGenerateActivates = FALSE;
  763. }
  764.  
  765. //--------------------------------------------------------------------------------------------------
  766. #pragma segment MAOpen
  767.  
  768. pascal void TFloatWindow::IRes(TDocument* itsDocument,
  769.                                TView* itsSuperView,
  770.                                Ptr& itsParams)
  771.  
  772. {
  773.     Point saveStdWTopleft;
  774.  
  775.     saveStdWTopleft = gStdWSizeRect[topLeft];
  776.     gStdWSizeRect[topLeft] = gZeroPt;
  777.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  778.     gStdWSizeRect[topLeft] = saveStdWTopleft;
  779.  
  780.     fHideOnSuspend = TRUE;
  781.     fDoFirstClick = TRUE;
  782.     fFloats = TRUE;
  783.     ((WindowPeek)fWMgrWindow)->windowKind = kFloatWindowKind;// mark it as a floating window 
  784.     fGenerateActivates = FALSE;
  785. }
  786.  
  787. //--------------------------------------------------------------------------------------------------
  788. #pragma segment MAOpen
  789.  
  790. pascal WindowPtr TFloatWindow::GetBehindWindowPtr(void)
  791.  
  792. {
  793.     return (WindowPtr) - 1;                        // bring the float window up in front of all
  794.     // other windows
  795. }
  796.  
  797. //--------------------------------------------------------------------------------------------------
  798. #pragma segment MAOpen
  799. pascal TEvtHandler* TFloatWindow::GetNextHandler(void)// override 
  800.  
  801. {
  802.     return inherited::GetNextHandler();
  803.     /*
  804.       TWindow    activeWindow;
  805.       activeWindow = gApplication->GetActiveWindow();
  806.       if (activeWindow)
  807.       return activeWindow.GetTarget();
  808.       else
  809.       return gApplication;
  810.     */
  811. }
  812.  
  813. //--------------------------------------------------------------------------------------------------
  814. #pragma $Push
  815. #if qTrace
  816. #pragma $D+
  817. #endif
  818.  
  819. #pragma $R-
  820. #pragma $V-
  821. // called from patches 
  822. #pragma segment MAWindowRes
  823.  
  824. pascal void MAClipAbove(WindowPtr window)
  825. // fixes ROM anomaly in which ClipAbove clips to the current clip rgn.
  826. //    we assume the current port is the window mgr port
  827.  
  828. {
  829.     SetClip(GetGrayRgn());
  830.     ClipAbove((WindowPeek)window);
  831. }
  832. #pragma $Pop
  833.  
  834. //--------------------------------------------------------------------------------------------------
  835. #pragma $Push
  836. #if qTrace
  837. #pragma $D+
  838. #endif
  839.  
  840. #pragma $R-
  841. #pragma $V-
  842. #pragma segment MAWindowRes
  843.  
  844. pascal void DeactivateSystemWindow(WindowPtr window)
  845. // dehilite && deactivate hilited system windows 
  846.  
  847. {
  848.     WindowPtr cacheActivate;
  849.     EventRecord theEvent;
  850.  
  851.     if (((WindowPeek)window)->hilited)
  852.     {
  853.         // save CurActivate so that EventAvail gives us the Deactivate event 
  854.         cacheActivate = *((WindowPtrPtr)CurActivate);
  855.         *((WindowPtrPtr)CurActivate) = NULL;
  856.  
  857.         // de-hilite the system window 
  858.         HiliteWindow(window, FALSE);
  859.  
  860.         // process the deactivate event 
  861.         *((WindowPtrPtr)CurDeactive) = window;    // set curDeactive 
  862.         *((IntegerPtr)CurDeKind) = ((WindowPeek)window)->windowKind;
  863.         if (EventAvail(activMask, theEvent))    // gimme that deactivate! 
  864.             if ((theEvent.what == activateEvt) && ((theEvent.modifiers & 1) != 1) && (((WindowPtr)theEvent.message) == window) && SystemEvent(theEvent))
  865.                 *((WindowPtrPtr)CurDeactive) = NULL;// zap it, it got handled 
  866.  
  867.             // restore CurActivate 
  868.         *((WindowPtrPtr)CurActivate) = cacheActivate;
  869.     }
  870. }
  871.  
  872.  
  873. pascal void SendSystemWindowsToBack(void)
  874. // send system windows behind all windows 
  875.  
  876. {
  877.     WindowPeek nextWindow;
  878.     WindowPeek thisWindow;
  879.     WindowPeek lastWindow;
  880.     short itsWindowKind;
  881.  
  882.     // find out which non-system window is the last window 
  883.     lastWindow = (WindowPeek)FrontWindow();
  884.     CWMgrIterator iter;
  885.     
  886.     for (thisWindow = (WindowPeek)iter.FirstWMgrWindow(); iter.More(); thisWindow = (WindowPeek)iter.NextWMgrWindow())
  887.     {
  888.         itsWindowKind = ((WindowPeek)thisWindow)->windowKind;
  889.         if ((itsWindowKind >= 0) && (itsWindowKind < kTHINKWindowKind))
  890.             lastWindow = thisWindow;
  891.     }
  892.     
  893.  
  894.     // iterate until no more windows or we've reached the last window 
  895.     thisWindow = (WindowPeek)FrontWindow();
  896.     while ((thisWindow) && (thisWindow != lastWindow))
  897.     {
  898.         nextWindow = thisWindow->nextWindow;    /* what is it *NOW* before we munge the
  899.                                                   window list */
  900.         if (thisWindow->windowKind < 0)            // if it's a System window 
  901.         {
  902.             FixedSendBehind((WindowPtr)thisWindow, NULL, FALSE);// send thisWindow to back 
  903.             DeactivateSystemWindow((WindowPtr)thisWindow);
  904.         }
  905.         thisWindow = nextWindow;
  906.     }
  907. }
  908. #pragma $Pop
  909.  
  910. //--------------------------------------------------------------------------------------------------
  911. #pragma segment MAInit
  912.  
  913. pascal void InitUFloatWindow(void)
  914.  
  915. {
  916.     if (qTemplateViews && gDeadStripSuppression)
  917.         DontDeadStrip(TFloatWindow);            // So the linker doesn't dead strip these 
  918.  
  919.     // install window mgr patches 
  920.     FailOSErr(PatchTrap(pBringToFrontPatch, _BringToFront, (Ptr) & MABringToFront));
  921.     FailOSErr(PatchTrap(pDragWindowPatch, _DragWindow, (Ptr) & MADragWindow));
  922.     FailOSErr(PatchTrap(pSelectWindowPatch, _SelectWindow, (Ptr) & MASelectWindow));
  923.     FailOSErr(PatchTrap(pMoveWindowPatch, _MoveWindow, (Ptr) & MAMoveWindow));
  924.     FailOSErr(PatchTrap(pZoomWindowPatch, _ZoomWindow, (Ptr) & MAZoomWindow));
  925.     FailOSErr(PatchTrap(pShowWindowPatch, _ShowWindow, (Ptr) & MAShowWindow));
  926.     FailOSErr(PatchTrap(pShowHidePatch, _ShowHide, (Ptr) & MAShowHide));
  927.     
  928.     // Only patch _HiliteWindow if called from NewDialog or from CloseDialog
  929.     //FailOSErr(PatchTrap(pHiliteWindowPatch, _HiliteWindow, (Ptr) & MAHiliteWindow));
  930.     FailOSErr(PatchTrap(pNewDialogPatch, _NewDialog, (Ptr) & MANewDialog));
  931.  
  932.     // tail patch to GNE which redirects activate/deactivate events 
  933.     FailOSErr(PatchTrap(pGetNextEventPatch, _GetNextEvent, (Ptr) & MAGetNextEvent));
  934.  
  935.     // !!! no constant since as of System 7 this trap is still private
  936.     pHasLayerMgr = TrapExists(0xA829);
  937.  
  938.     pDuringSelectWindow = FALSE;
  939.     gUFloatWindowInitialized = TRUE;
  940. }
  941.  
  942.  
  943.